package wang.relish.widget.vehicleedittext;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.text.InputType;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import relish.wang.vehicleedittext.R;


/**
 * 输入框键盘绑定帮助类
 * @author huyi
 * @since 2019/09/18
 */
public class VehicleKeyboardHelper implements OnkeyCallBack {
    private final Context context;
    private final List<EditText> editTexts;
    private final KeyBoardCallBackListener keyBoardCallBackListener;
    private final OnkeyBoardActionListener onkeyBoardActionListener;
    private final View boardView;

    public VehicleKeyboardHelper(Context context, List<EditText> editTexts, KeyBoardCallBackListener keyBoardCallBackListener) {
        this.context = context;
        this.editTexts = editTexts;
        this.keyBoardCallBackListener = keyBoardCallBackListener;
        boardView = LayoutInflater.from(context).inflate(R.layout.layout_vehiclekeyboard, null);
        VehicleKeyboardView keyboardView = boardView.findViewById(R.id.keyboardView);
        onkeyBoardActionListener = new OnkeyBoardActionListener(keyboardView, this);
        init();
    }

    private void init() {
        bindOntouchListener();
    }

    private void bindOntouchListener() {
        if (editTexts == null || editTexts.size() == 0) return;
        for (EditText editText : editTexts) {
            editListener(editText);
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private void editListener(final EditText et) {
        // 设置触摸的点击事件。为了显示光标。（直接设置InputType.TYPE_NULL的话光标会消失）
        et.setOnTouchListener((v, event) -> {
            //int inType = et.getInputType();
            hideSoftInputMethod(et);
            //et.setInputType(inType);
            // 光标始终在内容的最后面
            et.setSelection(et.getText().length());
            et.onTouchEvent(event);
            return true;
        });
        // 监听输入框的焦点事件：获得焦点显示自定义键盘；失去焦点收起自定义键盘
        et.setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus) {
                et.setTag(true);
                hideSysInput(et);
                onkeyBoardActionListener.setmEditText(et);
                showCustomInput(et);
            } else {
                et.setTag(false);
                checkHideCustomInput();
            }
            if(keyBoardCallBackListener != null){
                keyBoardCallBackListener.onFocusChange(v,hasFocus);
            }
        });
        // 监听物理返回键，收起自定义键盘
        et.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    removeFocus();
                    return true;
                }
                return false;
            }
        });
    }


    /**
     * 检测是否需要隐藏
     */
    private void checkHideCustomInput() {
        if (editTexts == null || editTexts.size() == 0) return;
        new Handler().postDelayed(() -> {
            boolean isClose = true;
            for (EditText editText : editTexts) {
                if (editText.getTag() != null && (boolean) (editText.getTag())) {
                    isClose = false;
                    break;
                }
            }
            if (isClose) {//全部失去焦点，则关闭键盘
                hideCustomInput();
            }
        }, 200);
    }

    /**
     * 为EditText绑定车牌号输入键盘
     *
     * @param editTexts 绑定的输入框控件(EditText)
     */
    public static VehicleKeyboardHelper bind(Context context, List<EditText> editTexts, KeyBoardCallBackListener voiceRecongin) {
        return new VehicleKeyboardHelper(context, editTexts, voiceRecongin);
    }

    /**
     * 展示自定义键盘
     *
     * @param et 输入框控件
     */
    private void showCustomInput(final EditText et) {
        PopupHelper.showToWindow(getWindow(), boardView);
        scrollViewEditTop(et);
    }

    /**
     * 隐藏自定义键盘
     */
    private void hideCustomInput() {
        PopupHelper.dismissFromWindow(getWindow());
        if(keyBoardCallBackListener != null){
            keyBoardCallBackListener.softKeyBoardClose();
        }
    }

    /**
     * scrollview 的输入框滚动到popupwindow之上
     *
     * @param et
     */
    private void scrollViewEditTop(final EditText et) {
        final View view = getWindow().getDecorView().findViewById(R.id.keyboard_wrapper_id);
        if (view == null) {
            return;
        }
        view.post(new Runnable() {
            @Override
            public void run() {
                final int[] keyBordLocation = new int[2];
                view.getLocationOnScreen(keyBordLocation);
                //获取输入框的位置
                final int[] editLocation = new int[2];
                et.getLocationOnScreen(editLocation);
                if (editLocation[1] + et.getHeight() > keyBordLocation[1]) {
                    if (keyBoardCallBackListener != null) {
                        keyBoardCallBackListener.scrollBy(editLocation[1] + et.getHeight() - keyBordLocation[1]);
                    }
                }
            }
        });
    }

    /**
     * 清除焦点
     */
    public void removeFocus() {
        if (editTexts == null || editTexts.size() == 0) return;
        if (!isActivityRunning()) return;
        for (EditText et : editTexts) {
            if (et.getTag() != null && (boolean) (et.getTag())) {
                View parent = (View) et.getParent();
                if (parent != null) {
                    parent.setFocusable(true);
                    parent.setFocusableInTouchMode(true);
                    parent.requestFocus();
                }
                et.clearFocus();
            }
        }
    }

    /**
     * 隐藏系统输入法
     *
     * @param et 输入框控件
     */
    private void hideSysInput(EditText et) {
        IBinder windowToken = et.getWindowToken();
        if (windowToken != null) {
            InputMethodManager imm = (InputMethodManager)
                    et.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    private Window getWindow() {
        if (context == null) {
            return null;
        }
        if (context instanceof Activity) {
            return ((Activity) context).getWindow();
        } else {
            Log.e("VehicleEditText", "EditText must have a Context which is a Activity.");
            return null;
        }
    }

    private boolean isActivityRunning() {
        if (context == null) return false;
        if (context instanceof Activity) {
            return !((Activity) context).isFinishing();
        } else {
            return false;
        }
    }

    /**
     * 禁掉系统软键盘
     */
    public void hideSoftInputMethod(EditText et) {
        int currentVersion = android.os.Build.VERSION.SDK_INT;
        String methodName = null;
        if (currentVersion >= 16) {
            // 4.2
            methodName = "setShowSoftInputOnFocus";
        } else if (currentVersion >= 14) {
            // 4.0
            methodName = "setSoftInputShownOnFocus";
        }
        if (methodName == null) {
            et.setInputType(InputType.TYPE_NULL);
        } else {
            Class<EditText> cls = EditText.class;
            Method setShowSoftInputOnFocus;
            try {
                setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class);
                setShowSoftInputOnFocus.setAccessible(true);
                setShowSoftInputOnFocus.invoke(et, false);
            } catch (NoSuchMethodException e) {
                et.setInputType(InputType.TYPE_NULL);
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 点击键盘外侧关闭以及当前键盘绑定的edittext外侧关闭
     *
     * @param ev
     */
    public void dispatchTouchEvent(MotionEvent ev) {
        boolean isOutSide = true;
        if (editTexts != null && editTexts.size() > 0) {
            for (EditText editText : editTexts) {
                if (!isOutSideInput(editText, ev)) {
                    isOutSide = false;
                    break;
                }
            }
        }
        View view = getWindow().getDecorView().findViewById(R.id.keyboard_wrapper_id);
        if (isOutSide && isOutSideInput(view, ev)) {
            removeFocus();
        }
    }

    /**
     * 点击的点是否在view的外侧
     *
     * @param v  检测的view
     * @param ev 点击的点
     * @return
     */
    private boolean isOutSideInput(View v, MotionEvent ev) {
        if (v != null) {
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left
                    + v.getWidth();
            return !(ev.getX() > left) || !(ev.getX() < right) || !(ev.getY() > top)
                    || !(ev.getY() < bottom);

        }
        return false;
    }

    @Override
    public void close() {
        removeFocus();
    }

    @Override
    public void voice() {
        removeFocus();
        if (keyBoardCallBackListener != null) {
            keyBoardCallBackListener.voiceCallBack();
        }
    }
}
